#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <sys/time.h>

#define BUFSIZE	32
#define CPS		10	 // 速率
#define BURST	((CPS) * 10) // 上限
#define CNT		10

// 漏桶

static int token; // 令牌

static void sig_handler(int s)
{
	token += CPS;
	if (token > BURST)
		token = BURST;
}

int mycpy_sysio(int rfd, int wfd);
int main(int argc, char *argv[])
{
	int fd1;

	if (argc < 2)
		return 1;

	fd1 = open(argv[1], O_RDONLY);
	if (-1 == fd1) {
		// 打印失败的原因
		printf("errno:%d, err_string:%s\n", errno, strerror(errno));
		perror("open()函数调用失败");
		return 1;
	}

	mycpy_sysio(fd1, 1);

	close(fd1);
	
	return 0;
}

int mycpy_sysio(int rfd, int wfd)
{
	char buf[BUFSIZE] = {0};
	int cnt;
	struct sigaction act = {};
	struct sigaction oldact;
	struct itimerval itv, old_itv;

	// 控制io流量
	act.sa_handler = sig_handler;
	sigaction(SIGALRM, &act, &oldact);
	itv.it_interval.tv_sec = 1;
	itv.it_interval.tv_usec = 0;
	itv.it_value.tv_sec = 1;
	itv.it_value.tv_usec = 0;
	setitimer(ITIMER_REAL, &itv, &old_itv);

	while (1) {
		// 控制流量
		while (token < CNT) {
			pause();	
		}
		token -= CNT;
		memset(buf, 0, BUFSIZE);
		cnt = read(rfd, buf, CNT);
		if (0 == cnt)
			break;
		else if (-1 == cnt) {
			perror("失败函数是read()");
			return -1;
		}
		write(wfd, buf, cnt);	
	}
	sigaction(SIGALRM, &oldact, NULL);
	setitimer(ITIMER_REAL, &old_itv, NULL);

	return 0;
}



